const { Controller } = require("egg");
const { sendCode, sendMassEmail } = require('../tool/mail');
const bcrypt = require("bcrypt"); // 用于加密密码（推荐）
const jwt = require('jsonwebtoken');

class HomeController extends Controller {
  async insertUser() {
    const { ctx, app } = this;
    try {
      const {
        email,
        name,
        organization,
        researchField,
        verificationCode,
        password,
        confirmPassword,
      } = ctx.request.body;

      // 1. 校验密码一致性
      if (password !== confirmPassword) {
        ctx.body = { code: 400, msg: "Passwords do not match." };
        return;
      }

      // 2. 从 Redis 获取验证码
      const redisKey = `verify_code_${email}`;
      const realCode = await app.redis.get(redisKey);

      if (!realCode) {
        ctx.body = { code: 400, msg: "Verification code expired or missing." };
        return;
      }

      if (realCode !== verificationCode) {
        ctx.body = { code: 400, msg: "Verification code is incorrect." };
        return;
      }

      // 3. 加密密码（推荐使用 bcrypt）
      const saltRounds = 10;
      const hashedPassword = await bcrypt.hash(password, saltRounds);

      // 4. 插入或更新用户信息
      const [user, created] = await ctx.model.User.upsert({
        email,
        name,
        organization,
        researchField,
        password: hashedPassword, // 保存加密后的密码
        role: 0
      });

      // 5. 可选：注册成功后删除验证码
      await app.redis.del(redisKey);
      const userData = user.toJSON(); // 转为普通对象
      delete userData.password;       // 删除密码字段

      ctx.body = {
        code: 200,
        msg: created
          ? "User created successfully."
          : "User updated successfully.",
        data: userData,
      };
    } catch (error) {
      ctx.body = { code: 500, msg: "Insertion failed: " + error.message };
    }
  }
  async queryUser() {
    const { ctx } = this;
    try {
      const currentPage = parseInt(ctx.query.currentPage) || 1;
      const pageSize = parseInt(ctx.query.pageSize) || 10;
      const offset = (currentPage - 1) * pageSize;

      const condition = {
        attributes: { exclude: ["deletedAt", "updatedAt", "password"] }, // 排除敏感字段
        limit: pageSize,
        offset: offset,
        order: [["createdAt", "DESC"]], // 按ID倒序
      };
      if (ctx.query.name) {
        condition.where = {
          name: {
            [Op.like]: `%${ctx.query.name}%`, // 名字模糊查询
          },
        };
      }
      const { count, rows } = await ctx.model.User.findAndCountAll(condition);

      ctx.body = {
        code: 200,
        data: {
          list: rows,
          pagination: {
            total: count,
            currentPage: currentPage,
            pageSize: pageSize,
            totalPages: Math.ceil(count / pageSize),
          },
        },
      };
    } catch (error) {
      ctx.body = { code: 500, msg: "Query failed:" + error.message };
    }
  }
  async sendEmailCode() {
    const { ctx, app } = this;
    try {
      const { email } = ctx.request.body;
      const code = Math.floor(100000 + Math.random() * 900000).toString();

      await sendCode(email, code); // 发邮件
      const redisKey = `verify_code_${email}`;
      await app.redis.set(redisKey, code, 'EX', 600); // 设置验证码，10分钟过期
      ctx.body = {
        code: 200,
        msg: 'successfully'
      };
    } catch (error) {
      ctx.body = { code: 500, msg: "failed:" + error.message };
    }
  }
  async login() {
    const { ctx, app } = this;

    try {
      const { email, password } = ctx.request.body;

      if (!email || !password) {
        ctx.body = { code: 400, msg: 'Email and password are required' };
        return;
      }

      // 从数据库查找用户（这里假设你有一个 user 表）
      const user = await ctx.model.User.findOne({ where: { email } });

      if (!user) {
        ctx.body = { code: 401, msg: 'User not found' };
        return;
      }

      // 比对加密后的密码
      const isMatch = await bcrypt.compare(password, user.password);
      if (!isMatch) {
        ctx.body = { code: 401, msg: 'Incorrect password' };
        return;
      }

      // 生成永久有效的 token（不设置 expiresIn）
      const token = jwt.sign(
        {
          id: user.id,
          email: user.email,
        },
        app.config.jwt.secret
        // 不设置 expiresIn 表示永不过期
      );
      const userData = user.toJSON();
      delete userData.password;
      ctx.body = {
        code: 200,
        msg: 'Login successful',
        user: {
          ...userData,
          token,
        },
      };
    } catch (error) {
      ctx.body = { code: 500, msg: 'Login failed: ' + error.message };
    }
  }
  async resetPassword() {
    const { ctx, app } = this;
    try {
      const { email, code, newPassword } = ctx.request.body;

      // Redis key
      const redisKey = `verify_code_${email}`;

      // 从 Redis 获取验证码
      const savedCode = await app.redis.get(redisKey);

      if (!savedCode) {
        ctx.body = { code: 401, msg: 'Verification code expired or not found' };
        return;
      }

      if (savedCode !== code) {
        ctx.body = { code: 401, msg: 'Invalid verification code' };
        return;
      }

      // 查找用户
      const user = await ctx.model.User.findOne({ where: { email } });
      if (!user) {
        ctx.body = { code: 404, msg: 'User not found' };
        return;
      }

      // bcrypt 加密新密码
      const saltRounds = 10;
      const hashedPassword = await bcrypt.hash(newPassword, saltRounds);

      // 更新用户密码
      user.password = hashedPassword;
      await user.save();

      // 删除 Redis 中的验证码
      await app.redis.del(redisKey);

      ctx.body = { code: 200, msg: 'Password reset successfully' };
    } catch (error) {
      ctx.body = { code: 500, msg: 'Reset password failed: ' + error.message };
    }
  }
  async massEmail() {
    const { ctx } = this;
    const { recipients, subject, html } = ctx.request.body;

    const emails = recipients.split(',').map(e => e.trim()).filter(Boolean);

    const { successList, failedList } = await sendMassEmail(emails, subject, html);

    ctx.body = {
      success: failedList.length === 0,
      total: emails.length,
      successCount: successList.length,
      failedCount: failedList.length,
      failedList: failedList.map(f => f.email),
      message: failedList.length === 0 ? '全部邮件发送成功' : '部分邮件发送失败',
    };
  }
  async queryEmail() {
    const { ctx } = this;
    try {
      const emails = await ctx.model.User.findAll({
        attributes: ['email'], // 只查 email 字段
      });

      const emailList = emails.map(item => item.email);

      ctx.body = {
        code: 200,
        msg: 'Email list fetched successfully',
        data: emailList,
      };
    } catch (err) {
      ctx.body = {
        code: 500,
        msg: 'Failed to fetch email list: ' + err.message,
      };
    }
  }
  async log() {
    const { ctx } = this;
    const { type, userId, msg } = ctx.request.body;
    if (!type || !userId || !msg) {
      ctx.body = { code: 400, message: '参数不完整' };
      return;
    }
    try {
      const log = await ctx.model.Log.create({ type, userId, msg });
      ctx.body = { code: 200, message: '日志记录成功', data: log };
    } catch (error) {
      ctx.logger.error(error);
      ctx.body = { code: 500, message: '日志记录失败', error: error.message };
    }

  }

}

module.exports = HomeController;
